#include <cstdio>
#include <iostream>
#include <iterator>

namespace list {
template <int...> struct t {};

template <int i, typename T> struct push_front {};
template <int i, int... xs> struct push_front<i, t<xs...>> {
  using value = t<i, xs...>;
};

// list -> list -> list -> list
template <typename L, typename M, typename R> struct concat {};
template <int... L, int... M, int... R>
struct concat<t<L...>, t<M...>, t<R...>> {
  using value = t<L..., M..., R...>;
};

// list<...> -> int
template <typename T> struct sum {};
template <> struct sum<t<>> { static constexpr int value = 0; };
template <int i, int... xs> struct sum<t<i, xs...>> {
  static constexpr int value = i + sum<t<xs...>>::value;
};
} // namespace list

// bool -> 'a -> 'a -> 'a
template <bool, typename T, typename F> struct _if {};
template <typename T, typename F> struct _if<true, T, F> { using value = T; };
template <typename T, typename F> struct _if<false, T, F> { using value = F; };

// int -> int -> bool
template <int A> struct gt {
  template <int B> struct t { static constexpr bool value = A < B; };
};

// int -> int -> bool
template <int A> struct le {
  template <int B> struct t { static constexpr bool value = A >= B; };
};

// list<...> -> (int -> bool) -> list<...>
template <typename T, template <int> class Test> struct filter {};
template <template <int> class Test> struct filter<list::t<>, Test> {
  using value = list::t<>;
};
template <template <int> class Test, int i, int... xs>
struct filter<list::t<i, xs...>, Test> {
  using _rest = typename filter<list::t<xs...>, Test>::value;
  using value =
      typename _if<Test<i>::value, typename list::push_front<i, _rest>::value,
                   _rest>::value;
};

// list -> list
template <typename T> struct qs {};
template <> struct qs<list::t<>> { using value = list::t<>; };
// template <int i> struct qs<list::t<i>> { using value = list::t<i>; };

template <int i, int... xs> struct qs<list::t<i, xs...>> {
  template <int x> using _gtifn = typename gt<i>::template t<x>;
  using _big = typename filter<list::t<xs...>, _gtifn>::value;

  template <int x> using _leifn = typename le<i>::template t<x>;
  using _small = typename filter<list::t<xs...>, _leifn>::value;

  using value = typename list::concat<typename qs<_big>::value, list::t<i>,
                                      typename qs<_small>::value>::value;
};

template <int... vals> void print(list::t<vals...>) {
  static constexpr int values[] = {vals...};
  std::copy(std::begin(values), std::end(values),
            std::ostream_iterator<int>(std::cout, " "));
  std::endl(std::cout);
}

#include <iostream>
int main() {
  using l1 = list::t<3, 2, 1, 5, 6, 4, 9, 8, 7, 2, 33, 22, 88, 44>;
  print(l1());

  using y = qs<l1>::value;
  print(y());
  return 0;
}